#import "SuotaPlugin.h"

static int SCAN_TIMEOUT = 10000;
@implementation SuotaPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel* channel = [FlutterMethodChannel
                                     methodChannelWithName:@"suota"
                                     binaryMessenger:[registrar messenger]];
    SuotaPlugin* instance = [[SuotaPlugin alloc] init];
    [registrar addMethodCallDelegate:instance channel:channel];
    //   event channel 初始化
    instance.eventChannel = [FlutterEventChannel eventChannelWithName:@"updateEventChannel"  binaryMessenger:[registrar messenger]];
    // 设置代理
    [instance.eventChannel setStreamHandler:instance];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([@"getPlatformVersion" isEqualToString:call.method]) {
        
        
        result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
    }else if([@"startUpdate" isEqualToString:call.method]){
        self.suotaScanner = [SuotaScanner scannerWithBuilderBlock:^(ScannerBuilder* builder){
            builder.viewController = [[UIViewController alloc]init];
            NSLog(@"scannerWithBuilderBlock");
        }];
        // event channel 初始化
        //    self.eventChannel = [FlutterEventChannel eventChannelWithName:@"updateEventChannel" binaryMessenger:self];
        //
        //    // 设置代理
        //    [self.eventChannel setStreamHandler:self];
        
        //接受传递的参数
        //      NSDictionary* argsMap=call.arguments;
        
  
        NSDictionary* argsMap=call.arguments;
//        NSLog(@"argsMap %@",argsMap);
        self.filePath =argsMap[@"filePath"];
        self.name =argsMap[@"name"];
        self.ishaveDevice = false;
//        NSLog(@"self.filePath %@",self.filePath);
//        NSLog(@"self.name %@"  , self.name);
//        self.filePath = call.arguments;
        if (!self.suotaScanner)
            @throw [NSException exceptionWithName:@"SuotaScannerException" reason:@"Can't create SUOTA scanner" userInfo:nil];
              [self scan];
        
        result(@"test ");
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onTerminate) name:UIApplicationWillTerminateNotification object:nil];

    }else if([@"disconnect" isEqualToString:call.method]){
        NSLog(@"suota disconnect");
        [self disconnect];
    }else {
        result(FlutterMethodNotImplemented);
    }
}
-(void)onTerminate {

    NSLog(@"杀掉进程");
    [self disconnect];

}

- (void) scan {
    if (self.suotaScanner.isScanning) {
        NSLog(@"Already scanning");
    } else {
        NSLog(@"Start  dd scanning");
        NSLog(@"%@", self);
        if([self.suotaScanner respondsToSelector:@selector(scan:)]){
            NSLog(@"能够响应");
        }else{
            NSLog(@"不能够响应");
        }
        NSLog(@"%@", self.suotaScanner);
        [self.suotaScanner scan:self scanTimeout:SCAN_TIMEOUT];
    }
}
#pragma mark  SuotaScannerDelegate

- (void) onFailure:(enum ScanFailure)failure{
    NSLog(@"failure");
    NSLog(@"%u",failure);
    self.eventSink(@{@"onManagerFailure":[NSString stringWithFormat:@"%d",failure]});
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
}

- (void) onScanStatusChange:(enum ScanStatus)newStatus{
    NSLog(@"newStatus xxx%u",newStatus);

    
//    NSLog(@"state xxx%u",self.suotaManager.state);
    //停止扫描
    if(newStatus == STOPPED){
        
        if(self.ishaveDevice == false){
            self.eventSink(@{@"onManagerFailure":@"未找到设备,升级失败"});
            [[NSNotificationCenter defaultCenter] removeObserver:self];
            return;
        }    
        NSLog(@"我来了 xxx%u",newStatus);
        if (self.suotaManager.state == DEVICE_DISCONNECTED) {
//            NSLog(@"我来了suotaManager xxx%u",self.suotaManager.state);
//            //连接设备
//            NSLog(@"设备准备连接");
            [self.suotaManager connect];
//            NSLog(@"设备准备连接完成");

        }
    }
    
    
}
- (void) onDeviceScan:(CBPeripheral*)peripheral rssi:(NSNumber*)rssi scanRecord:(NSDictionary*)scanRecord {
//    NSLog(@"onDeviceScan");
//    NSLog(@"onDeviceScan xxx %@",peripheral.name);
//    NSLog(@"onDevicename xxx %@",self.name);
//    NSLog(@"onDevicexxis xxx %ld", [self.name isEqualToString:peripheral.name]);
    //正式版本直接通过名字判断
    
    if( [self.name isEqualToString:peripheral.name]){
        NSLog(@"找到设备可以开始升级 %@",self.name);
        self.ishaveDevice = true;
        //设置peripheral
        self.peripheral = peripheral;
       
        //设置管理器
        self.suotaManager = [[SuotaManager alloc] initWithPeripheral:self.peripheral suotaManagerDelegate:self];
    }

    
    //设置peripheral 测试 拿到扫描的第一个
    // self.peripheral = peripheral;
    // //设置管理器
    // self.suotaManager = [[SuotaManager alloc] initWithPeripheral:self.peripheral suotaManagerDelegate:self];
    
    //    NSUInteger index = [self.scannedDevices indexOfObjectPassingTest:^BOOL (ScannedDevice* device, NSUInteger index, BOOL* stop){
    //        return *stop = [device.peripheral.identifier isEqual:peripheral.identifier];
    //    }];
    //    if (index == NSNotFound) {
    //        [self.scannedDevices addObject:[[ScannedDevice alloc] initWithPeripheral:peripheral rssi:rssi]];
    //        [self updateList:true];
    //    } else {
    //        self.scannedDevices[index].rssi = rssi;
    //        [self updateList:false];
    //    }
}


#pragma mark - SuotaManagerDelegate

- (void) onConnectionStateChange:(enum SuotaManagerStatus)newStatus {
    
    if (newStatus != DISCONNECTED)
        return;
    
    SuotaLog(@"SuotaPlugin", @"Services discovered");
    self.eventSink(@{@"onManagerFailure":@"手环手动断了连接"});
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
}

- (void) onServicesDiscovered {
    SuotaLog(@"SuotaPlugin", @"Services discovered");
}

- (void) onCharacteristicRead:(enum CharacteristicGroup)characteristicGroup characteristic:(CBCharacteristic*)characteristic {
    SuotaLog(@"SuotaPlugin", @"onCharacteristicRead");
    //    NSUInteger index = [self.viewControllers indexOfObjectPassingTest:^BOOL (UIViewController* viewController, NSUInteger index, BOOL* stop){
    //        return *stop = [viewController isKindOfClass:DeviceViewController.class];
    //    }];
    //    if (index != NSNotFound && characteristicGroup == DEVICE_INFO)
    //        [(DeviceViewController*)self.viewControllers[index] onCharacteristicRead:characteristic.UUID value:[[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]];
}

- (void) onDeviceInfoReadCompleted:(enum DeviceInfoReadStatus)status {
    SuotaLog(@"SuotaPlugin", @"onInfoReadCompleted");
}

//设备以及准备好了可以开始升级
- (void) onDeviceReady {
    SuotaLog(@"SuotaPlugin", @"onDeviceReady");
    
    //    NSUInteger index = [self.viewControllers indexOfObjectPassingTest:^BOOL (UIViewController* viewController, NSUInteger index, BOOL* stop){
    //        return *stop = [viewController isKindOfClass:DeviceViewController.class];
    //    }];
    //    if (index != NSNotFound)
    //        [(DeviceViewController*)self.viewControllers[index] onDeviceReady];
//    NSString* url =[[NSBundle mainBundle] pathForResource:@"pxp_reporter.1.0.0.1" ofType:@"img"];
//    NSLog(@"url 结果");
//    NSLog(@"%@",url);
//    self.suotaManager.suotaFile = [SuotaFile loadFileWithPath:url];
    self.suotaManager.suotaFile = [SuotaFile loadFileWithPath:self.filePath];

    // [self.suotaManager initializeSuota:240 misoGpio:5 mosiGpio:6 csGpio:3 sckGpio:0 imageBank:0];
    [self.suotaManager initializeSuota:2880 misoGpio:5 mosiGpio:6 csGpio:3 sckGpio:0 imageBank:0];
    [self.suotaManager startUpdate];
    
  
}

- (void) onSuotaLog:(enum SuotaProtocolState)state type:(enum SuotaLogType)type log:(NSString*)log {
    SuotaLog(@"SuotaPlugin", @"");
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController onSuotaLog:state type:type log:log];
    //    }
}
//数据传输的代理
- (void) onChunkSend:(int)chunkCount totalChunks:(int)totalChunks chunk:(int)chunk block:(int)block blockChunks:(int)blockChunks totalBlocks:(int)totalBlocks {
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController onChunkSend:chunkCount totalChunks:totalChunks chunk:chunk block:block blockChunks:blockChunks totalBlocks:totalBlocks];
    //    }
}

- (void) onBlockSent:(int)block totalBlocks:(int)totalBlocks {
}
//升级进度
- (void) onUploadProgress:(float)percent {
//    NSString *logString =[NSString stringWithFormat:@"%f",percent];
    int progress = (int)percent;

    NSString *logString =[NSString stringWithFormat:@"%d", progress];
    NSLog(@"logString %@",logString);
    if (self.eventSink) {
        self.eventSink(@{@"process":logString});
    }
    
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController onUploadProgress:percent];
    //    }
}

- (void) onSuccess:(double)totalElapsedSeconds imageUploadElapsedSeconds:(double)imageUploadElapsedSeconds {
    NSLog(@"onSuccess imageUploadElapsedSeconds");
    self.eventSink(@{@"onSuccess":@"0"});
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    self.eventSink = nil;
    //手环重启
    // [self.suotaManager sendRebootCommand];
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController onSuccess:totalElapsedSeconds imageUploadElapsedSeconds:imageUploadElapsedSeconds];
    //    }
}
//
- (void) onManagerFailure:(int)errorCode {
    NSLog(@"onManagerFailure");
    self.eventSink(@{@"onManagerFailure":[NSString stringWithFormat:@"%d",errorCode]});
    NSLog(@"%@",[NSString stringWithFormat:@"%d",errorCode]);
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    //    if (errorCode != INVALID_FIRMWARE_CRC && [self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController notifySuotaFailed];
    //    }
    //    [self displayAlert:@"An Error Occurred" message:SuotaProfile.suotaErrorCodeList[@(errorCode)] dismissViewController:errorCode != INVALID_FIRMWARE_CRC];
}

- (void) onRebootSent {
    NSLog(@"onRebootSent");
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController onRebootSent];
    //    }
}

- (void) updateSpeedStatistics:(double)current max:(double)max min:(double)min avg:(double)avg {
    NSLog(@"updateSpeedStatistics");
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController updateSpeedStatistics:current max:max min:min avg:avg];
    //    }
}

- (void) updateCurrentSpeed:(double)currentSpeed {
    NSLog(@"updateCurrentSpeed");
    //    if ([self.topViewController isKindOfClass:SUOTAViewController.class]) {
    //        [(SUOTAViewController*)self.topViewController updateCurrentSpeed:currentSpeed];
    //    }
}
#pragma mark FlutterStreamHandler

- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
                                       eventSink:(FlutterEventSink)events{
    
    self.eventSink = events;
    // arguments flutter给native的参数
    // 回调给flutter， 建议使用实例指向，因为该block可以使用多次
//    if (events) {
//        events(@"主动发送通知到flutter");//回调给flutter
//    }
    ///可以在此做一些事
    NSLog(@"======%@", arguments);
    return nil;
    
}


- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments{
    self.eventSink = nil;
    return  nil;
    
}
//断开连接
-(void)disconnect{
    if(self.suotaManager  != nil){
        [self.suotaManager disconnect];
    }

}
@end
